package com.xiaotou.weibo;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;
import weibo4j.http.RequestToken;

import com.xiaotou.db.dao.WbUserDAO;
import com.xiaotou.db.dao.AppUserDAO;
import com.xiaotou.db.pojo.AppUser;
import com.xiaotou.db.pojo.ObjectFactory;
import com.xiaotou.db.pojo.SinaUser;
import com.xiaotou.db.pojo.WbUser;
import com.xiaotou.utils.AuthUtils;
import com.xiaotou.weibo.appData.AbstractAppOauthData;

@Component("oauthUtils")
public class OauthUtilsSinaImpl extends OauthUtils {
	static Log logger = LogFactory.getLog(OauthUtilsSinaImpl.class);

	private WbUserDAO wbUserDao;

	private AppUserDAO appUserDao;

	public void setWbUserDao(WbUserDAO sinaUserDao) {
		this.wbUserDao = sinaUserDao;
	}

	public void setAppUserDao(AppUserDAO appUserDao) {
		this.appUserDao = appUserDao;
	}

	@Override
	public String getAuthrizeURL(AbstractAppOauthData appOauthData,
			HttpServletRequest request) {
		String authenticationURL = "";
		Weibo wb = new Weibo();
		wb.setOAuthConsumer(appOauthData.getConsumerKey(),
				appOauthData.getConsumerSecret());
		RequestToken oAuthRequestToken;
		try {
			String callbackUrl = getCallbackUrl(request);
			oAuthRequestToken = wb.getOAuthRequestToken(callbackUrl);
			AuthUtils.setTokenSecret(oAuthRequestToken.getTokenSecret());
			authenticationURL = oAuthRequestToken.getAuthenticationURL();
		} catch (WeiboException e) {
			logger.error("error when getAuthrizeURL", e);
		}

		return authenticationURL;
	}

	@Override
	protected String getCallbackUrl(HttpServletRequest request) {
		return request.getScheme() + "://" + request.getServerName() + ":"
				+ request.getServerPort() + "/wbcallback.action?wbType="
				+ WbConstent.WBTYPE_SINA;
	}

	@Override
	@Transactional
	public WbUser storeAccessTokenAndAccessTokenSecret(
			AbstractAppOauthData appOauthData) {

		WbUser wbUser = null;
		Weibo wb = new Weibo();
		wb.setOAuthConsumer(appOauthData.getConsumerKey(),
				appOauthData.getConsumerSecret());
		String token = appOauthData.getToken();
		String tokenSecret = appOauthData.getTokenSecret();
		String oauth_verifier = appOauthData.getVerifier();

		AccessToken oAuthAccessToken;
		try {
			oAuthAccessToken = wb.getOAuthAccessToken(token, tokenSecret,
					oauth_verifier);
			String accessToken = oAuthAccessToken.getToken();
			String accessTokenSecret = oAuthAccessToken.getTokenSecret();
			User wbuser = wb.verifyCredentials();
			if (wbuser != null) {
				WbUser userFromDB = this.wbUserDao.findByWbId(wbuser.getId());
				if (userFromDB == null) {
					AppUser xtUser = ObjectFactory.newbie();
					xtUser.setRegisterTime(new Date());
					this.appUserDao.save(xtUser);
					wbUser = storeWbUser(accessToken, accessTokenSecret,
							wbuser, xtUser);
				} else {
					userFromDB.setAccesstoken(accessToken);
					userFromDB.setAccesstokenserect(accessTokenSecret);
					userFromDB.setProfileImageUrl(wbuser.getProfileImageUrl());
					AppUser user = userFromDB.getAppUser();
					userFromDB.setAppUser(user);
					this.wbUserDao.update(userFromDB);
					wbUser = userFromDB;
				}
			}
		} catch (WeiboException e) {
			logger.error("error when storeAccessTokenAndAccessTokenSecret", e);
		}
		return wbUser;
	}

	private WbUser storeWbUser(String accessToken, String accessTokenSecret,
			User wbuser, AppUser xtUser) {
		SinaUser sinaUser = new SinaUser();
		sinaUser.bindFromUser(wbuser);

		sinaUser.setAppUser(xtUser);
		sinaUser.setAccesstoken(accessToken);
		sinaUser.setAccesstokenserect(accessTokenSecret);
		this.wbUserDao.save(sinaUser);
		return sinaUser;
	}

	@Override
	public void sycToopoosSource(AbstractAppOauthData appData) throws Exception {
	}

}
